import tkinter as tk
from tkinter import ttk, messagebox
import pymysql
import datetime
import time
import os

# 数据库连接配置
DB_CONFIG = {
    'host': 'localhost',
    'port': 3306,
    'user': 'XWZH',
    'passwd': '123456',
    'db': 'hospital',
    'charset': 'utf8'
}


class HospitalSystem:
    def __init__(self):
        self.connect = pymysql.Connect(**DB_CONFIG)
        self.cursor = self.connect.cursor()
        self.current_user = None

    def check_credentials(self, user_id, password):
        """验证用户登录信息"""
        valid_ids = ['XWZH', 'PXOZ', 'WOTN', 'LHTP']
        valid_passwords = ['123456', '123456', '123456', '123456']
        return user_id in valid_ids and password in valid_passwords

    def query_work_of_department(self):
        sql = """
        SELECT
            dp.dpname AS '科室名称',
            YEAR(p.startdate) AS '年份',
            WEEK(p.startdate) AS '周数',
            COUNT(p.pno) AS '新入院人数',
            GROUP_CONCAT(p.pname ORDER BY p.startdate) AS '患者列表'
        FROM department dp
        JOIN room r ON dp.dpno = r.dpno
        JOIN patient p ON r.rno = p.rno
        GROUP BY dp.dpname, YEAR(p.startdate), WEEK(p.startdate)
        ORDER BY dp.dpname, YEAR(p.startdate) DESC, WEEK(p.startdate) DESC;
        """
        self.cursor.execute(sql)
        return self.cursor.fetchall()

    def query_work_of_doctor(self):
        """查询医生工作量"""
        sql = """
        SELECT
            d.dno AS '医生编号',
            d.dname AS '医生姓名',
            dp.dpname AS '所属科室',
            COUNT(p.pno) AS '负责患者数'
        FROM doctor d
        LEFT JOIN patient p ON d.dno = p.dno
        LEFT JOIN department dp ON d.dpno = dp.dpno
        GROUP BY d.dno, d.dname, dp.dpname
        ORDER BY COUNT(p.pno) DESC;
        """
        self.cursor.execute(sql)
        return self.cursor.fetchall()

    def query_treatment_of_patient(self):
        """查询病人治疗情况"""
        sql = """
        SELECT
            p.pno AS '患者编号',
            p.pname AS '姓名',
            p.illness AS '病症',
            d.dname AS '主治医生',
            dp.dpname AS '所属科室',
            GROUP_CONCAT(DISTINCT dg.dgname SEPARATOR ', ') AS '使用药物',
            SUM(pd.num * dg.dgprice) AS '总药费'
        FROM patient p
        JOIN doctor d ON p.dno = d.dno
        JOIN department dp ON d.dpno = dp.dpno
        LEFT JOIN PD pd ON p.pno = pd.pno
        LEFT JOIN drug dg ON pd.dgno = dg.dgno
        GROUP BY p.pno, p.pname, p.illness, d.dname, dp.dpname;
        """
        self.cursor.execute(sql)
        return self.cursor.fetchall()

    def close(self):
        self.cursor.close()
        self.connect.close()


class LoginWindow:
    def __init__(self, master, app):
        self.master = master
        self.app = app
        master.title("医院信息管理系统 - 登录")
        master.geometry("400x300")
        master.configure(bg="#f0f8ff")
        try:
            master.iconbitmap("hospital_icon.ico")
        except:
            pass

        title_label = tk.Label(master, text="医院信息管理系统", font=("微软雅黑", 20, "bold"), bg="#f0f8ff",
                               fg="#2c3e50")
        title_label.pack(pady=20)
        login_frame = tk.Frame(master, bg="#ffffff", bd=2, relief=tk.GROOVE)
        login_frame.pack(pady=20, padx=40, fill=tk.BOTH, expand=True)

        tk.Label(login_frame, text="用户名:", font=("微软雅黑", 12), bg="#ffffff").grid(row=0, column=0, padx=10,
                                                                                        pady=15, sticky="e")
        self.username_entry = tk.Entry(login_frame, font=("微软雅黑", 12))
        self.username_entry.grid(row=0, column=1, padx=10, pady=15, sticky="we")

        tk.Label(login_frame, text="密  码:", font=("微软雅黑", 12), bg="#ffffff").grid(row=1, column=0, padx=10,
                                                                                        pady=15, sticky="e")
        self.password_entry = tk.Entry(login_frame, show="*", font=("微软雅黑", 12))
        self.password_entry.grid(row=1, column=1, padx=10, pady=15, sticky="we")

        button_frame = tk.Frame(login_frame, bg="#ffffff")
        button_frame.grid(row=2, column=0, columnspan=2, pady=20)

        login_button = tk.Button(button_frame, text="登 录", command=self.login,
                                 font=("微软雅黑", 12), bg="#3498db", fg="white", width=10)
        login_button.pack(side=tk.LEFT, padx=10)

        exit_button = tk.Button(button_frame, text="退 出", command=master.quit,
                                font=("微软雅黑", 12), bg="#e74c3c", fg="white", width=10)
        exit_button.pack(side=tk.LEFT, padx=10)

        login_frame.columnconfigure(1, weight=1)

        self.username_entry.insert(0, "XWZH")
        self.password_entry.insert(0, "123456")

    def login(self):
        username = self.username_entry.get()
        password = self.password_entry.get()

        if not username or not password:
            messagebox.showerror("输入错误", "用户名和密码不能为空")
            return

        if self.app.check_credentials(username, password):
            self.app.current_user = username
            self.master.destroy()  # 关闭登录窗口
            root = tk.Tk()
            app = MainWindow(root, self.app)
            root.mainloop()
        else:
            messagebox.showerror("登录失败", "用户名或密码错误")


class MainWindow:
    def __init__(self, master, app):
        self.master = master
        self.app = app
        master.title("医院信息管理系统")
        master.geometry("1200x700")
        master.configure(bg="#ecf0f1")

        try:
            master.iconbitmap("hospital_icon.ico")
        except:
            pass

        self.create_menu()

        self.create_main_interface()

    def create_menu(self):
        menu_bar = tk.Menu(self.master)

        file_menu = tk.Menu(menu_bar, tearoff=0)
        file_menu.add_command(label="退出系统", command=self.master.quit)
        menu_bar.add_cascade(label="文件", menu=file_menu)

        query_menu = tk.Menu(menu_bar, tearoff=0)
        query_menu.add_command(label="科室排班情况", command=self.show_department_schedule)
        query_menu.add_command(label="医生工作情况", command=self.show_doctor_workload)
        query_menu.add_command(label="病人治疗情况", command=self.show_patient_treatment)
        menu_bar.add_cascade(label="查询", menu=query_menu)

        help_menu = tk.Menu(menu_bar, tearoff=0)
        help_menu.add_command(label="关于", command=self.show_about)
        menu_bar.add_cascade(label="帮助", menu=help_menu)

        self.master.config(menu=menu_bar)

    def create_main_interface(self):
        header_frame = tk.Frame(self.master, bg="#3498db", height=80)
        header_frame.pack(fill=tk.X)

        title_label = tk.Label(header_frame, text="医院信息管理系统",
                               font=("微软雅黑", 24, "bold"), bg="#3498db", fg="white")
        title_label.pack(pady=20)

        self.status_var = tk.StringVar()
        self.status_var.set(f"欢迎您，{self.app.current_user} | 就绪")
        status_bar = tk.Label(self.master, textvariable=self.status_var,
                              bd=1, relief=tk.SUNKEN, anchor=tk.W, bg="#bdc3c7")
        status_bar.pack(side=tk.BOTTOM, fill=tk.X)


        main_frame = tk.Frame(self.master, bg="#ecf0f1")
        main_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)

        button_frame = tk.Frame(main_frame, bg="#ecf0f1")
        button_frame.pack(fill=tk.X, pady=10)

        buttons = [
            ("科室排班情况", self.show_department_schedule, "#1abc9c"),
            ("医生工作情况", self.show_doctor_workload, "#3498db"),
            ("病人治疗情况", self.show_patient_treatment, "#9b59b6"),
            ("退出系统", self.master.quit, "#e74c3c")
        ]

        for text, command, color in buttons:
            btn = tk.Button(button_frame, text=text, command=command,
                            font=("微软雅黑", 12), bg=color, fg="white",
                            width=15, height=2)
            btn.pack(side=tk.LEFT, padx=10, pady=5)


        result_frame = tk.LabelFrame(main_frame, text="查询结果",
                                     font=("微软雅黑", 12), bg="#ecf0f1")
        result_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        self.tree = ttk.Treeview(result_frame)
        self.tree.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        scrollbar = ttk.Scrollbar(result_frame, orient="vertical", command=self.tree.yview)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.tree.configure(yscrollcommand=scrollbar.set)

    def show_department_schedule(self):
        """显示科室排班情况"""
        self.status_var.set("正在查询科室排班情况...")
        self.master.update()

        try:
            results = self.app.query_work_of_department()
            self.clear_tree()
            columns = ("科室名称", "年份", "周数", "新入院人数", "患者列表")
            self.tree["columns"] = columns
            self.tree["show"] = "headings"
            col_widths = [150, 60, 60, 100, 300]
            for col, width in zip(columns, col_widths):
                self.tree.heading(col, text=col)
                self.tree.column(col, width=width, anchor="center")
            for row in results:
                self.tree.insert("", "end", values=row)

            self.status_var.set(f"科室排班情况查询完成，共 {len(results)} 条记录")
        except Exception as e:
            messagebox.showerror("查询错误", f"查询科室排班情况时出错:\n{str(e)}")
            self.status_var.set("查询失败")

    def show_doctor_workload(self):
        """显示医生工作情况"""
        self.status_var.set("正在查询医生工作情况...")
        self.master.update()

        try:
            results = self.app.query_work_of_doctor()

            self.clear_tree()

            columns = ("医生编号", "医生姓名", "所属科室", "负责患者数")
            self.tree["columns"] = columns
            self.tree["show"] = "headings"


            col_widths = [100, 150, 150, 100]
            for col, width in zip(columns, col_widths):
                self.tree.heading(col, text=col)
                self.tree.column(col, width=width, anchor="center")


            for row in results:
                self.tree.insert("", "end", values=row)

            self.status_var.set(f"医生工作情况查询完成，共 {len(results)} 条记录")
        except Exception as e:
            messagebox.showerror("查询错误", f"查询医生工作情况时出错:\n{str(e)}")
            self.status_var.set("查询失败")

    def show_patient_treatment(self):
        """显示病人治疗情况"""
        self.status_var.set("正在查询病人治疗情况...")
        self.master.update()

        try:
            results = self.app.query_treatment_of_patient()


            self.clear_tree()


            columns = ("患者编号", "姓名", "病症", "主治医生", "所属科室", "使用药物", "总药费")
            self.tree["columns"] = columns
            self.tree["show"] = "headings"


            col_widths = [80, 80, 120, 100, 100, 200, 80]
            for col, width in zip(columns, col_widths):
                self.tree.heading(col, text=col)
                self.tree.column(col, width=width, anchor="center")


            for row in results:
                self.tree.insert("", "end", values=row)

            self.status_var.set(f"病人治疗情况查询完成，共 {len(results)} 条记录")
        except Exception as e:
            messagebox.showerror("查询错误", f"查询病人治疗情况时出错:\n{str(e)}")
            self.status_var.set("查询失败")

    def clear_tree(self):

        for item in self.tree.get_children():
            self.tree.delete(item)


        self.tree["columns"] = []

    def show_about(self):

        about_text = "医院信息管理系统\n版本: 1.0\n开发人员: 陈锦辉, 许雪雯"
        messagebox.showinfo("关于", about_text)


if __name__ == "__main__":

    hospital_app = HospitalSystem()


    login_root = tk.Tk()
    login_app = LoginWindow(login_root, hospital_app)
    login_root.mainloop()


    hospital_app.close()
